package net.kong.sns.rest.client;

import net.kong.org.springframework.util.StopWatch;
import net.kong.org.springframework.util.StringUtils;
import net.kong.sns.rest.client.cache.EhCacheFactory;
import net.kong.sns.rest.client.cache.KongCacheNames;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;

/**
 * 创建客户端
 *
 * @author <a href="mailto:lanhuai@gmail.com">Ning Yubin</a>
 * @version $Id: ClientFactory.java,v 1.6.2.2 2009/12/09 09:10:27 ningyubin Exp $
 */
public abstract class ClientFactory {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientFactory.class);

    private static final String DEFAULT_APP_PROPERTIES = "kong_app.properties";

    private ClientFactory() {
    }

    /**
     * 创建Client,需要SessionKey,apiKey与apiSecret存放在 /WEB-INF/classes/kong_app.properties 中,<br/>
     * kong_app.properties内容如下：<br/>
     * apiKey=xxxxxxx<br/>
     * apiSecret=xxxxxxx<br/>
     *
     * @param sessionKey SessionKey
     * @return Client
     * @throws IOException 读取 /WEB-INF/classes/kong_app.properties 出错
     */
    public static Client createInstance(String sessionKey) throws IOException {
        InputStream inputStream = ClientFactory.class.getClassLoader().getResourceAsStream(DEFAULT_APP_PROPERTIES);
        AppKeysFile appKeysFile = new AppKeysFile(inputStream);
        Ehcache cache = EhCacheFactory.getInstance().getCache(KongCacheNames.CLIENTS_WITH_SESSIONKEY.name());
        String apiKey = appKeysFile.getApiKey();
        String apiSecret = appKeysFile.getApiSecret();
        final String clientCacheKey = clientCacheKey(sessionKey, apiKey, apiSecret);
        Element element = cache.get(clientCacheKey);
        if (element != null) {
            return (Client) element.getObjectValue();
        } else {
            Client client = new ClientImpl(sessionKey, appKeysFile);
            element = new Element(clientCacheKey, client);
            cache.put(element);
            return client;
        }
    }

    private static String clientCacheKey(String sessionKey, String apiKey, String apiSecret) {
        return StringUtils.arrayToDelimitedString(new String[]{sessionKey, apiKey, apiSecret}, "_");
    }

    private static String clientCacheKey(String apiKey, String apiSecret) {
        return StringUtils.arrayToDelimitedString(new String[]{apiKey, apiSecret}, "_");
    }

    /**
     * 创建Client,不需要SessionKey,apiKey与apiSecret存放在 /WEB-INF/classes/kong_app.properties 中,<br/>
     * kong_app.properties内容如下：<br/>
     * apiKey=xxxxxxx<br/>
     * apiSecret=xxxxxxx<br/>
     * @return Client
     * @throws IOException 读取 /WEB-INF/classes/kong_app.properties 出错
     */
    public static Client createInstance() throws IOException {
        InputStream inputStream = ClientFactory.class.getClassLoader().getResourceAsStream(DEFAULT_APP_PROPERTIES);
        AppKeysFile appKeysFile = new AppKeysFile(inputStream);
        Ehcache cache = EhCacheFactory.getInstance().getCache(KongCacheNames.CLIENTS_WITHOUT_SESSIONKEY.name());
        String apiKey = appKeysFile.getApiKey();
        String apiSecret = appKeysFile.getApiSecret();
        final String clientCacheKey = clientCacheKey(apiKey, apiSecret);
        Element element = cache.get(clientCacheKey);
        if (element != null) {
            return (Client) element.getObjectValue();
        } else {
            Client client = new ClientImpl(appKeysFile);
            element = new Element(clientCacheKey, client);
            cache.put(element);
            return client;
        }
    }

    /**
     * 创建Client,需要SessionKey
     * @param sessionKey SessionKey
     * @param apiKey apiKey
     * @param apiSecret apiSecret
     * @return Client
     */
    public static Client createInstance(String sessionKey, String apiKey, String apiSecret) {
        StopWatch stopWatch = new StopWatch("Create Client Instance ");
        stopWatch.start(String.format("Get Cache[%s]", KongCacheNames.CLIENTS_WITH_SESSIONKEY.name()));
        Ehcache cache = EhCacheFactory.getInstance().getCache(KongCacheNames.CLIENTS_WITH_SESSIONKEY.name());
        stopWatch.stop();

        Client retValue;
        stopWatch.start("Get Client from Cache");
        final String clientCacheKey = clientCacheKey(sessionKey, apiKey, apiSecret);
        Element element = cache.get(clientCacheKey);
        stopWatch.stop();
        if (element != null) {
            retValue = (Client) element.getObjectValue();
        } else {
            AppKeysFile appKeysFile = new AppKeysFile();
            appKeysFile.setApiKey(apiKey);
            appKeysFile.setApiSecret(apiSecret);

            stopWatch.start("Pew Client instance ");
            Client client = new ClientImpl(sessionKey, appKeysFile);
            stopWatch.stop();

            stopWatch.start("Put Client instance into Cache");
            element = new Element(clientCacheKey, client);
            cache.put(element);
            stopWatch.stop();
            retValue = client;
        }
        LOGGER.info(stopWatch.prettyPrint());
        return retValue;
    }

    /**
     * 创建Client,不需要SessionKey
     * @param apiKey apiKey
     * @param apiSecret apiSecret
     * @return Client
     */
    public static Client createInstance(String apiKey, String apiSecret) {
        AppKeysFile appKeysFile = new AppKeysFile();
        appKeysFile.setApiKey(apiKey);
        appKeysFile.setApiSecret(apiSecret);
        Ehcache cache = EhCacheFactory.getInstance().getCache(KongCacheNames.CLIENTS_WITHOUT_SESSIONKEY.name());
        final String clientCacheKey = clientCacheKey(apiKey, apiSecret);
        Element element = cache.get(clientCacheKey);
        if (element != null) {
            return (Client) element.getObjectValue();
        } else {
            Client client = new ClientImpl(appKeysFile);
            element = new Element(clientCacheKey, client);
            cache.put(element);
            return client;
        }
    }
}
